package com.yeqing.netty;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class ByteBufferTest {

    /**
     * ByteBuffer基本使用，读取文件内容并打印
     * @throws Exception
     */
    public static void readAndPrint() throws Exception {

        try(
                // 获取Channel
                FileChannel channel = new FileInputStream("/Users/cyq/Develop/三国/张飞22.txt").getChannel();
            ) {
            // 创建ByteBuffer
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            // 读取文件内容，并存入buffer
            channel.read(buffer);

            // 切换到读模式
            buffer.flip();
            while (buffer.hasRemaining()) {
                System.out.println((char) buffer.get());
//                System.out.println(StandardCharsets.UTF_8.decode(buffer));
            }

            // 清空缓冲区，并重置为写模式
            buffer.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testMark() {
        ByteBuffer buffer = ByteBuffer.allocate(32);
        buffer.put("hello".getBytes(StandardCharsets.UTF_8));
        System.out.println("记录put后的信息：" + buffer);
        buffer.mark();
        System.out.println("记录mark后的信息：" + buffer);
        buffer.put("world".getBytes(StandardCharsets.UTF_8));
        System.out.println("再次记录put后的信息：" + buffer);
        buffer.reset();
        System.out.println("记录reset后的信息：" + buffer);
    }

    /**
     * 测试get方法和get(i)方法：get()会读取当前数据，并移到下一个下标，get(i)读取i的数据
     * 测试rewind方法：把position移到0，再次put时，会覆盖0下标的数据
     */
    public static void byteBufferTest() {
        ByteBuffer buffer = ByteBuffer.allocate(5);
        buffer.put("hello".getBytes(StandardCharsets.UTF_8));
        System.out.println(buffer);
        buffer.flip();
        System.out.println(buffer);
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        buffer.rewind();
        buffer.put("8".getBytes(StandardCharsets.UTF_8));
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
//        System.out.println((char) buffer.get());
//        System.out.println((char) buffer.get());
    }

    public static void main(String[] args) throws Exception {
//        readAndPrint();

        // class java.nio.HeapByteBuffer
        // Java堆内存，读写效率较低，收到gc影响
//        System.out.println(ByteBuffer.allocate(1024).getClass());
        // class java.nio.DirectByteBuffer
        // 直接内存，读写效率较高（少一次拷贝）不会收到gc影响，分配内存效率较低，使用不当则可能会发生内存泄露
//        System.out.println(ByteBuffer.allocateDirect(1024).getClass());

//        testMark();
        byteBufferTest();
    }
}
